gusucode.com > VC++ RingSDK界面库 > VC++ RingSDK界面库/code/libsrc/ringdows/ringtab.cpp

    /**********************************************************************
//
//
//        ##########                          ######  #########   # ######    #
//      #############                      ########### ######### #########  ###
//     ######## # ###  ##                 ############# ##    ## #####  # ####
//     ####  ##    ## ###                 ###     ### # #      #####   #####
//          #     ###  #            #     ##       ##  ##      ##     ###
//         ## ###### ##      ##  ####    ####          #       #     ##
//       #########  ###  ## ### #######   ######      ##      ##    ###
//      ######      ##  ######  ##  ##       ####     #      ##     ####
//     #######     ##   ###### ##  ###          ##   ##     ###    ######
//     #########   ##  ###### ## ######         ### ##    ###      #  #####
//    ##    ###### ####### ### #### ##  ## #######  ########      ##    ####
//    ##      #### ###  #  ### ### ##  ##########   ######       ##      ####
//   ##         ##                ##   #########    ####         #         ##
//               #              ###
//                              ##
//                             ###
//                             ##
//
//
//							临风程序界面类库 ringdows.lib
//作者:临风
//
//版本:1.0
//
//声明:本类库可以自由使用而不须对作者作出任何回报,但作者希望能得到
//		  你的鼓励和支持。你可以对类库源码作出修改和改进,但希望你能在
//		  修改的同时给作者一份同样的副本。
//		  本类库不得用于任何商业用途,如确实需要,请与作者联系。
//
//e-mail:ringphone@sina.com
//
//原文件名:ringtab.cpp
//
//说明:tab控件控制
//
**********************************************************************/
#define MAKE_SELF_LIB
#include "ringdows.h"

RingTab::RingTab()
{
	m_windowType = ITIS_TAB;
	m_hImage = NULL;
	m_CurrTabWindow = NULL;
	m_dockbar = NULL;
	m_nCheckPos = 0; 
}

RingTab::~RingTab()
{
	if(m_hImage)
		ImageList_Destroy(m_hImage);
}

BOOL RingTab::Attach(HWND hWnd)
{
	if(RingControls::Attach(hWnd))
	{		
		//去除CS_HREDRAW|CS_VREDRAW,否则调整尺寸引起窗口闪烁
		LONG lc = GetClassLong(m_hWnd,GCL_STYLE);
		lc &= ~(CS_HREDRAW|CS_VREDRAW);
		SetClassLong(m_hWnd,GCL_STYLE,lc);
		return TRUE;
	}
	return FALSE;
}

BOOL RingTab::Create(DWORD dwStyle,DWORD dwExStyle,LPCTSTR szInitText,UINT uId,int x,int y,int width,int height)
{
	InitCommonControls();
	
	if(RingControls::Create(dwStyle|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,dwExStyle,szInitText,uId,x,y,width,height))
	{
		//去除CS_HREDRAW|CS_VREDRAW,否则调整尺寸引起窗口闪烁
		LONG lc = GetClassLong(m_hWnd,GCL_STYLE);
		lc &= ~(CS_HREDRAW|CS_VREDRAW);
		SetClassLong(m_hWnd,GCL_STYLE,lc);
		return TRUE;
	}
	else
		return FALSE;
}

void RingTab::SetExStyle(DWORD dwExStyle)
{
	if(dwExStyle != 0 && m_hWnd)
	{
		//专有扩展属性必须用以下方法设置,
		DWORD dwStyle = SendMessage(m_hWnd,TCM_GETEXTENDEDSTYLE,0,0);
		dwStyle |= dwExStyle;
		SendMessage(m_hWnd,TCM_SETEXTENDEDSTYLE,0,dwStyle);
	}
}

HDWP RingTab::DefDeferWindowPos(HDWP hdwp,int x,int y,int width,int height,UINT uAppendFlag)
{
	//MoveWindow(m_hWnd,x,y,width,height,TRUE);
	//return hdwp;
	return DeferWindowPos(hdwp,m_hWnd,0,x,y,width,height,/*SWP_NOREDRAW|*/uAppendFlag);
		//SWP_NOZORDER|/*SWP_NOACTIVATE|*SWP_FRAMECHANGED|*/SWP_NOREDRAW|uAppendFlag);
}

RingDockBar* RingTab::EnableDock(LPCTSTR szTitle,UINT uDockStyle,
											UINT uDockFlag,LPRECT lprcPos)
{
	m_dockbar = RingBaseWnd::EnableDock(szTitle,uDockStyle,uDockFlag,lprcPos);
	return m_dockbar;
}

RingDockBar* RingTab::EnableDockSize(LPCTSTR szTitle,int nWidth,int nHeight,
												 UINT uDockFlag,UINT uDockStyle)
{
	m_dockbar = RingBaseWnd::EnableDockSize(szTitle,nWidth,nHeight,uDockFlag,uDockStyle);
	return m_dockbar;
}

BOOL RingTab::GetItemRect(int nIndex,LPRECT lprc)
{
	if(lprc)
		return TabCtrl_GetItemRect(m_hWnd,nIndex,lprc);
	else
		return FALSE;
}

/****************************************************
//
//TAB如果是多行标签,WM_SIZE消息里面调整子窗口尺寸时
//因为尚未调用WM_PAINT消息对标签进行绘制,如果标签行
//数变动,则TabCtrl_AdjustRect返回的仍是变动前的矩形,
//所以需要保存该矩形的top字段,WM_PAINT消息处理完后再
//次TabCtrl_AdjustRect,如果返回矩形与保存值不等,则
//表示标签行数变动,需要再次调整子窗口尺寸
//
//**************************************************/
void RingTab::CheckReposChild()
{
	RECT rc;
	GetClientRect(&rc);
	if(m_nCheckPos != rc.top)
	{
		m_nCheckPos = rc.top;
		::GetClientRect(m_hWnd,&rc);
		NotifyChild(m_hWnd,WM_SIZE,SIZE_RESTORED,MAKELONG(rc.right,rc.bottom));		
	}
}

LRESULT RingTab::RingdowProc(HWND,RINGPARAMS param)
{
	LRESULT res;

	switch(param.uMsg)
   {
		case WM_SIZE:
			InvalidateRect(m_hWnd,NULL,TRUE);
			//don't break;
		//case WM_ACTIVATE:
		//case WM_ENABLE:						
			NotifyChild(m_hWnd,param.uMsg,param.wParam,param.lParam);
			break;
		case WM_MEASUREITEM:
		case WM_DRAWITEM:
			NotifyChild(m_hWnd,param.uMsg,param.wParam,param.lParam);
			//Don't break;
		case WM_DELETEITEM:
		case WM_COMMAND:
		case WM_KEYPRESS:
			return SendMessage(m_parent->Handle(),param);
		case WM_ERASEBKGND:
			return TRUE;
		case WM_PAINT:
			return OnPaint(param);			
		case WM_NCDESTROY:
			//不把ImageList设置为空,窗口过程会销毁ImageList,导致
			//析构时ImageList_Destroy失败,BoundCheck报内存泄露,
			//但实际是否会内存泄露不清楚
			TabCtrl_SetImageList(m_hWnd,NULL);
			//DelBindWndData();
			CallWindowProc(m_DefProc,m_hWnd,param.uMsg,param.wParam,param.lParam);
			OnNcDestroy();
			return 0;
		default:
		{	
			res = CtlColorProc(m_hWnd,param);
			if(res == RM_NOTPROCESS)
				break;
			else
				return res;
		}
	}
	return RingControls::RingdowProc(m_hWnd,param);
}

BOOL RingTab::OnDrawBkg(HDC hDC)
{
	if((GetStyle() & (TCS_MULTILINE|TCS_OWNERDRAWFIXED)) == TCS_MULTILINE)
	{
		//多行标签且非自绘,避免多行标签闪烁
		int nCnt = GetCount();
		RECT rc;

		for(int i=0;i<nCnt;i++)
		{
			if(GetItemRect(i,&rc))
				ExcludeClipRect(hDC,rc.left,rc.top,rc.right,rc.bottom);
		}
	}
	return (m_dockbar && m_dockbar->DrawBkg(hDC));
}

LRESULT RingTab::OnPaint(RINGPARAMS& param)
{
	PAINTSTRUCT ps;
	LRESULT res;
	BeginPaint(m_hWnd,&ps);

	OnDrawBkg(ps.hdc);
	param.uMsg = WM_PRINTCLIENT;
	param.hdc = ps.hdc;
	res = RingControls::RingdowProc(m_hWnd,param);
	EndPaint(m_hWnd,&ps);
	CheckReposChild();
	return res;
}

LRESULT RingTab::OnDestroy(RINGPARAMS& param)
{
	DelBindWndData();
	return DefaultProc(param);
}

LRESULT RingTab::OnDefNotify(RingBaseWnd* w,RINGPARAMS& param)
{
	return OnTabSelect(param);	
}

int RingTab::AddIcon(UINT uidIcon,HINSTANCE hInst/*=GetInstance()*/)
{
	HICON hicon = LoadIcon(hInst,MAKEINTRESOURCE(uidIcon));
	return AddIcon(hicon);
}

int RingTab::AddIcon(HICON hicon)
{
	if(hicon == NULL)
		return -1;
	
	if(m_hImage == NULL)
	{
		m_hImage = ImageList_Create(16,16,ILC_COLOR32|ILC_MASK,5,5);
		if(m_hImage)
			TabCtrl_SetImageList(m_hWnd,m_hImage);
	}

	if(m_hImage)
		return ImageList_AddIcon(m_hImage,hicon);
	
	return -1;
}

BOOL RingTab::SetIcon(int indexTab,int indexIcon)
{
	TCITEM item;
	memset(&item,0,sizeof(TCITEM));
	
	item.mask = TCIF_IMAGE;

	if(TabCtrl_GetItem(m_hWnd,indexTab,&item))
	{
		item.iImage = indexIcon;
		
		return TabCtrl_SetItem(m_hWnd,indexTab,&item);
	}
	return FALSE;
}

BOOL RingTab::InsertTab(LPCTSTR szText,int subindex,UINT uidIcon)
{
	if(uidIcon != 0)
		uidIcon = AddIcon(uidIcon);

	TCITEM titem;
	memset(&titem,0,sizeof(TCITEM));
		
	if(uidIcon != -1)
	{
		titem.mask |= TCIF_IMAGE;
		titem.iImage = uidIcon;
	}
	if(szText)
	{
		titem.mask |= TCIF_TEXT;
		titem.pszText = (LPSTR)szText;
		titem.cchTextMax = strlen(szText);
	}
	return TabCtrl_InsertItem(m_hWnd,subindex,&titem);
}

BOOL RingTab::InsertTabs(LPCTSTR szText)
{	
	TCITEM titem;
	memset(&titem,0,sizeof(TCITEM));
		
	if(szText)
	{
		ringStr str = szText;
		int cnt = str.count("|") + 1;
		int start = 0;
		LPTSTR lps;

		titem.mask = TCIF_TEXT;
		for(int i=0;i<cnt;i++)
		{
			lps = (LPTSTR)str.string() + start;
			start = str.indexOf("|",start);
			if(str[start-1] == '\\')
			{
				start++;
				continue;
			}
			str[start] = '\0';

			titem.pszText = (LPSTR)(lps);
			titem.cchTextMax = strlen(lps);
			TabCtrl_InsertItem(m_hWnd,i,&titem);
			str[start++] = '\0';
		}
		return TRUE;
	}
	return FALSE;
}

BOOL RingTab::SetTabToWnd(int iCol,RingBaseWnd* wnd)
{
	TCITEM item;
	
	memset(&item,0,sizeof(TCITEM));

	item.mask = TCIF_PARAM;
	
	if(wnd && TabCtrl_GetItem(m_hWnd,iCol,&item))
	{
		if(item.lParam != 0)
			return FALSE;

		LPRINGTABITEMDATA lpdata = (LPRINGTABITEMDATA)New(sizeof(RINGTABITEMDATA));

		item.lParam = (LPARAM)lpdata;

		lpdata->uType = ITIS_WINDOW;
		lpdata->obj = wnd;

		if(!TabCtrl_SetItem(m_hWnd,iCol,&item))
			Del(lpdata);
		else
		{
			wnd->SetParent(m_hWnd);
			RECT rc;
			GetClientRect(&rc);
			wnd->SetPos(rc.left,rc.top);
			if(GetCurSel() == iCol)
			{
				m_CurrTabWindow = wnd;
				wnd->Show();
			}
			else
				wnd->Show(SW_HIDE);
			return TRUE;
		}
	}
	return FALSE;
}

int RingTab::Select(int iCol)
{
	int i = TabCtrl_SetCurSel(m_hWnd,iCol);

	NMHDR nm;
	nm.code = TCN_SELCHANGE;
	nm.hwndFrom = m_hWnd;
	nm.idFrom = GetId();

	SendMessage(m_parent->Handle(),WM_NOTIFY,GetId(),(LPARAM)&nm);
	return i;
}

LONG RingTab::GetItemData(int iCol)
{
	TCITEM item;
	
	memset(&item,0,sizeof(TCITEM));
	item.mask = TCIF_PARAM;

	if(TabCtrl_GetItem(m_hWnd,iCol,&item))
		return item.lParam;
	return 0;
}

void RingTab::DelBindWndData()
{
	int cnt = GetItemCount();
	TCITEM item;
	LPRINGTABITEMDATA lpdata;

	memset(&item,0,sizeof(TCITEM));
	
	item.mask = TCIF_PARAM;

	for(int i=0;i<cnt;i++)
	{
		if(TabCtrl_GetItem(m_hWnd,i,&item))
		{
			lpdata = (LPRINGTABITEMDATA)item.lParam;
			if(lpdata && lpdata->uType == ITIS_WINDOW)
			{
				try
				{
					Del(lpdata);
				}
				catch(...)
				{
				}
			}
		}
		item.lParam = 0;
	}
}

BOOL RingTab::GetClientRect(LPRECT lprc)
{
	if(lprc)
	{
		::GetClientRect(m_hWnd,lprc);
		TabCtrl_AdjustRect(m_hWnd,FALSE,lprc);
		return TRUE;
	}
	return FALSE;
}

LRESULT RingTab::OnTabSelect(RINGPARAMS& param)
{
	if(param.lpnmhdr && param.lpnmhdr->hwndFrom == m_hWnd)
	{
		if(param.lpnmhdr->code == TCN_SELCHANGE)
		{
			if(m_CurrTabWindow && IsWindowPtr(m_CurrTabWindow))
				m_CurrTabWindow->Show(SW_HIDE);

			int iCol = GetCurSel();
			LPRINGTABITEMDATA lpdata = (LPRINGTABITEMDATA)GetItemData(iCol);
			if(lpdata && lpdata->uType == ITIS_WINDOW)
			{
				m_CurrTabWindow = lpdata->obj;
				m_CurrTabWindow->Show(SW_SHOW);
			}
			return 0;
		}
	}
	//未处理的消息必须返回-1,由父窗口返回默认处理
	return -1;
}

int RingTab::GetItemText(int index,LPTSTR lpBuf,int size)
{
	TCITEM item;
	
	memset(&item,0,sizeof(TCITEM));
	item.mask = TCIF_TEXT;
	item.cchTextMax = size;
	item.pszText = (LPSTR)lpBuf;
	
	if(TabCtrl_GetItem(m_hWnd,index,&item))
		return item.cchTextMax;

	return 0;
}